package com.cosc716.restaurant.system;

import java.util.ArrayList;

import com.cosc716.restaurant.commands.Command;
import com.cosc716.restaurant.commands.Tables.CommandClearAllTables;
import com.cosc716.restaurant.commands.Tables.CommandGetAllTables;
import com.cosc716.restaurant.commands.Tables.CommandGetAvailableTables;
import com.cosc716.restaurant.commands.Tables.CommandGetOrderedTables;
import com.cosc716.restaurant.commands.Tables.CommandGetUnavailableTables;
import com.cosc716.restaurant.commands.Tables.CommandGetUnorderedTables;
import com.cosc716.restaurant.commands.Tables.CommandSeatCustomerGroup;
import com.cosc716.restaurant.commands.Tables.CommandUnSeatCustomerGroup;
import com.cosc716.restaurant.commands.customers.CommandAddCustomerGroupToQueue;
import com.cosc716.restaurant.commands.customers.CommandClearWaitingQueue;
import com.cosc716.restaurant.commands.customers.CommandGetWaitingQueue;
import com.cosc716.restaurant.commands.customers.CommandRemoveCustomerGroupFromQueue;
import com.cosc716.restaurant.commands.menu.CommandGetMenu;
import com.cosc716.restaurant.commands.orders.CommandAddOrder;
import com.cosc716.restaurant.commands.orders.CommandClearOrderQueue;
import com.cosc716.restaurant.commands.orders.CommandGetOrders;
import com.cosc716.restaurant.commands.orders.CommandRemoveOrder;
import com.cosc716.restaurant.domain.CustomerGroup;
import com.cosc716.restaurant.domain.Menu;
import com.cosc716.restaurant.domain.Order;
import com.cosc716.restaurant.domain.Table;
import com.cosc716.restaurant.domain.collections.OrderQueue;
import com.cosc716.restaurant.domain.collections.Tables;
import com.cosc716.restaurant.domain.collections.WaitingQueue;

public class SystemInterface {
	
	// private reference to Invoker singleton
	private Invoker invoker;
	
	// private ivar holds the singleton reference
	private static SystemInterface systemInterface;

	// prevent clients from using constructor
	private SystemInterface() {
		if (null == invoker) {
			invoker = Invoker.getInstance();
		}
	}
	
	public static SystemInterface getInstance() {
		if (null == systemInterface) {
			systemInterface = new SystemInterface();
		}
		
		return systemInterface;
	}
	
	// Menu
	public Menu getMenu() {
		Command command = new CommandGetMenu();
		Menu menu = (Menu)invoker.executeCommand(command);
		
		return menu;
	}
	
	public void printMenu() {
		Command command = new CommandGetMenu();
		Menu menu = (Menu)invoker.executeCommand(command);
		
		System.out.println(menu);
	}

	// Customers
	public void printWaitingQueue() {
		Command command = new CommandGetWaitingQueue();
		WaitingQueue object = (WaitingQueue)invoker.executeCommand(command);
		
		System.out.println(object);
	}
	
	public WaitingQueue getWaitingQueue() {
		Command command = new CommandGetWaitingQueue();
		WaitingQueue queue = (WaitingQueue)invoker.executeCommand(command);
		
		return queue;
	}
	
	public boolean addCustomerGroupToWaitingQueue(CustomerGroup group) {
		Command command = new CommandAddCustomerGroupToQueue(group);
		Boolean object = (Boolean)invoker.executeCommand(command);
		return object.booleanValue();
	}
	
	public boolean removeCustomerGroupFromWaitingQueue(CustomerGroup group) {
		Command command = new CommandRemoveCustomerGroupFromQueue(group);
		Boolean object = (Boolean)invoker.executeCommand(command);
		return object.booleanValue();
	}
	
	public void clearWaitingQueue() {
		Command command = new CommandClearWaitingQueue();
		invoker.executeCommand(command);
	}
	
	// Tables
	public void printTables() {
		Command command = new CommandGetAllTables();
		Tables tables = (Tables)invoker.executeCommand(command);
		
		System.out.println(tables);
	}
	
	public ArrayList<Table> getAvailableTables() {
		Command command = new CommandGetAvailableTables();
		ArrayList<Table> tables = (ArrayList<Table>)invoker.executeCommand(command);
		
		return tables;
	}
	
	public ArrayList<Table> getUnavailableTables() {
		Command command = new CommandGetUnavailableTables();
		ArrayList<Table> tables = (ArrayList<Table>)invoker.executeCommand(command);
		
		return tables;
	}
	
	public ArrayList<Table> getOrderedTables() {
		Command command = new CommandGetOrderedTables();
		ArrayList<Table> tables = (ArrayList<Table>)invoker.executeCommand(command);
		
		return tables;
	}
	
	public ArrayList<Table> getUnorderedTables() {
		Command command = new CommandGetUnorderedTables();
		ArrayList<Table> tables = (ArrayList<Table>)invoker.executeCommand(command);
		
		return tables;
	}
	
	public boolean addCustomersToTable(CustomerGroup group, Table table) {
		Command command = new CommandSeatCustomerGroup(group, table);
		Boolean object = (Boolean)invoker.executeCommand(command);
		return object.booleanValue();
	}
	
	public boolean removeCustomersFromTable(Table table) {
		Command command = new CommandUnSeatCustomerGroup(table);
		Boolean object = (Boolean)invoker.executeCommand(command);
		return object.booleanValue();
	}
	
	public void clearAllTables() {
		Command command = new CommandClearAllTables();
		invoker.executeCommand(command);
	}
	
	// Orders
	public void printOrders() {
		Command command = new CommandGetOrders();
		OrderQueue orders = (OrderQueue)invoker.executeCommand(command);
		
		System.out.println(orders);
	}
	
	public OrderQueue getOrders() {
		Command command = new CommandGetOrders();
		OrderQueue orders = (OrderQueue)invoker.executeCommand(command);
		
		return orders;
	}
	
	public boolean addOrder(Order order) {
		Command command = new CommandAddOrder(order);
		Boolean object = (Boolean)invoker.executeCommand(command);
		return object.booleanValue();
	}

	public boolean removeOrder(Order order) {
		Command command = new CommandRemoveOrder(order);
		Boolean object = (Boolean)invoker.executeCommand(command);
		return object.booleanValue();
	}
	
	public void clearOrderQueue() {
		Command command = new CommandClearOrderQueue();
		invoker.executeCommand(command);
	}

//	// Tabs
//	public void viewOpenTabs() {
//		// do stuff
//	}
//	
//	public void viewClosedTabs() {
//		// do stuff
//	}
//	
//	public boolean addOfferToTab() {
//		// do stuff
//		
//		return true;
//	}
	
	public void viewTotalSales() {
		// do stuff
	}
}
